package com.plan.base.util;

import com.plan.entity.user.User;

import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.URLDecoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Arrays;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class JsGlobalFunctions {
    private static final String CELL_PHONE_REGEX = "^((13[0-9])|(14[5,7,9])|(15[0-3,5-9])|(16[2,5,6,7])|(17[0,1,2,3,5-8])|(18[0-9])|(19[0|1|2|3|5|6|7|8|9]))\\d{8}$";
    private static final Pattern pattern = Pattern.compile("^((13[0-9])|(14[5,7,9])|(15[0-3,5-9])|(16[2,5,6,7])|(17[0,1,2,3,5-8])|(18[0-9])|(19[0|1|2|3|5|6|7|8|9]))\\d{8}$", 2);
    private static final String PASSWORD_PATTERN = "[0-9,a-z,A-Z]{32}";
    private static final String VERIFICATION_CODE_PATTERN = "[0-9]{6}";
    private static final String ACCOUNT_PATTERN = "[0-9,a-z,A-Z,_]{1,32}";
    private static final Pattern patternUUID = Pattern.compile("[0-9,a-z,A-Z]{32}", 2);
    private static final String QHD_REGEX = "^QHD\\d{18}$";
    private static final Pattern qhdPattern = Pattern.compile("^QHD\\d{18}$", 2);
    private static final String PFD_REGEX = "^PFD\\d{18}$";
    private static final Pattern pfdPattern = Pattern.compile("^PFD\\d{18}$", 2);
    private static final String PSD_REGEX = "^PSD\\d{18}$";
    private static final Pattern psdPattern = Pattern.compile("^PSD\\d{18}$", 2);
    private static final String YSKD_REGEX = "^YSKD\\d{18}$";
    private static final Pattern yskdPattern = Pattern.compile("^YSKD\\d{18}$", 2);
    private static final String PDD_REGEX = "^PDD\\d{18}$";
    private static final Pattern pddPattern = Pattern.compile("^PDD\\d{18}$", 2);
    private static final String BSD_REGEX = "^BSD\\d{18}$";
    private static final Pattern bsdPattern = Pattern.compile("^BSD\\d{18}$", 2);
    private static final String BYD_REGEX = "^BYD\\d{18}$";
    private static final Pattern bydPattern = Pattern.compile("^BYD\\d{18}$", 2);
    private static Set<Integer> orderYearRange = new HashSet();
    private static final Map<String, Integer> docPrefixTypeMap = new HashMap();

    public JsGlobalFunctions() {
    }


    public static boolean isUuid(String value) {
        if (value == null) {
            return false;
        } else {
            Matcher m = patternUUID.matcher(value);
            return m.matches();
        }
    }

    public static boolean isCellPhoneNumber(String value) {
        if (value == null) {
            return false;
        } else {
            Matcher m = pattern.matcher(value);
            return m.matches();
        }
    }


    public static boolean isPassword(String value) {
        return value != null && value.matches("[0-9,a-z,A-Z]{32}");
    }

    public static boolean isAccount(String value) {
        return value != null && value.matches("[0-9,a-z,A-Z,_]{1,32}");
    }


    public static String generateUUID() {
        return UUID.randomUUID().toString().replace("-", "");
    }

    public static String bytesToHexString(byte[] bytes) {
        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < bytes.length; ++i) {
            String hex = Integer.toHexString(255 & bytes[i]);
            if (hex.length() == 1) {
                sb.append('0');
            }

            sb.append(hex);
        }

        return sb.toString();
    }

    public static String getMd5(String arg0) {
        String md5Value = null;

        try {
            MessageDigest mDigest = MessageDigest.getInstance("MD5");
            mDigest.update(arg0.getBytes());
            md5Value = bytesToHexString(mDigest.digest()).toUpperCase();
        } catch (NoSuchAlgorithmException var3) {
            var3.printStackTrace();
        }

        return md5Value;
    }

    public static byte[] serialize(Object object) {
        ObjectOutputStream oos = null;
        ByteArrayOutputStream baos = null;

        try {
            baos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(baos);
            oos.writeObject(object);
            oos.flush();
            return baos.toByteArray();
        } catch (Exception var4) {
            return null;
        }
    }

    public static Object unSerialize(byte[] bytes) {
        try {
            ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes));
            return ois.readObject();
        } catch (Exception var2) {
            return null;
        }
    }


    public static User getUserFromToken(HttpServletRequest httpRequest) {
        Object token = httpRequest.getAttribute("token");
        return new User();
    }


    public static int convertBatchUpdateResultArrayToSingleResult(int[] retArray) {
        int result = 0;
        int[] var2 = retArray;
        int var3 = retArray.length;

        for (int var4 = 0; var4 < var3; ++var4) {
            int ret = var2[var4];
            if (ret >= 0) {
                result += ret;
            } else if (ret == -2) {
                ++result;
            }
        }

        return result;
    }


    public static boolean verify(HttpServletRequest request, String domain, String secret, Map<String, String> params) {
        boolean bNeedDecode = request.getMethod().equalsIgnoreCase("POST");
        Enumeration<String> paramKeys = request.getParameterNames();

        String key;
        String originalValue;
        while (paramKeys.hasMoreElements()) {
            key = (String) paramKeys.nextElement();

            try {
                originalValue = request.getParameter(key);
                if (bNeedDecode) {
                    params.put(key, URLDecoder.decode(originalValue, "utf-8"));
                } else {
                    params.put(key, originalValue);
                }
            } catch (UnsupportedEncodingException var8) {
                var8.printStackTrace();
            }
        }

        if (!params.containsKey("sig")) {
            return false;
        } else {
            key = (String) params.remove("sig");
            originalValue = sign(domain + request.getRequestURI(), params, secret);
            return key.compareToIgnoreCase(originalValue) == 0;
        }
    }

    public static boolean verify(HttpServletRequest request, String domain, String secret) {
        boolean bNeedDecode = request.getMethod().equalsIgnoreCase("POST");
        Enumeration<String> paramKeys = request.getParameterNames();
        Map<String, String> params = new HashMap();

        String key;
        String originalValue;
        while (paramKeys.hasMoreElements()) {
            key = (String) paramKeys.nextElement();

            try {
                originalValue = request.getParameter(key);
                if (bNeedDecode) {
                    params.put(key, URLDecoder.decode(originalValue, "utf-8"));
                } else {
                    params.put(key, originalValue);
                }
            } catch (UnsupportedEncodingException var8) {
                var8.printStackTrace();
            }
        }

        if (!params.containsKey("sig")) {
            return false;
        } else {
            key = (String) params.remove("sig");
            originalValue = sign(domain + request.getRequestURI(), params, secret);
            return key.compareToIgnoreCase(originalValue) == 0;
        }
    }

    public static String sign(String uri, Map<String, String> params, String secret) {
        String[] keys = (String[]) params.keySet().toArray(new String[0]);
        Arrays.sort(keys);
        StringBuilder sb = new StringBuilder();
        sb.append(uri).append("?");
        String[] var5 = keys;
        int var6 = keys.length;

        for (int var7 = 0; var7 < var6; ++var7) {
            String k = var5[var7];
            sb.append(k).append("=").append((String) params.get(k)).append("&");
        }

        sb.deleteCharAt(sb.length() - 1);
        sb.append(secret);
        return getMd5(sb.toString());
    }

    public static int encodeBigEndian(byte[] des, long value, int offset, int size) {
        for (int i = 0; i < size; ++i) {
            des[offset++] = (byte) ((int) (value >> (size - i - 1) * 8));
        }

        return offset;
    }

    public static long decodeBigEndian(byte[] value, int offset, int size) {
        long result = 0L;

        for (int i = 0; i < size; ++i) {
            result = result << 8 | (long) value[offset + i] & 255L;
        }

        return result;
    }


    public static int getRoundRobinIndex(AtomicInteger value, int arraySize) {
        int idx = value.getAndIncrement() % arraySize;
        if (idx == Integer.MIN_VALUE) {
            idx = 0;
        } else {
            idx = Math.abs(idx);
        }

        return idx;
    }

    public static int getDigitalYear(Date date) {
        Instant instant = date.toInstant();
        ZoneId zoneId = ZoneId.systemDefault();
        LocalDateTime localDateTime = instant.atZone(zoneId).toLocalDateTime();
        return localDateTime.getYear();
    }

    public static int pow(int value, int n) {
        int ret = value;

        for (int i = 1; i < n; ++i) {
            ret *= value;
        }

        return ret;
    }

    public static BigDecimal processNumberPrecision(BigDecimal value, Integer amountPrecision, Integer settlementAmountPrecision) {
        if (settlementAmountPrecision != -1) {
            return value.setScale(amountPrecision, settlementAmountPrecision);
        } else {
            String plainString = value.toPlainString();
            String[] amountPart = plainString.split("\\.");
            if (amountPart.length == 1) {
                return value;
            } else if (amountPart[1].length() <= amountPrecision) {
                return value;
            } else {
                int index = plainString.indexOf(46);
                String scaleValue = plainString.substring(0, index + amountPrecision + 1);
                char nextChar = plainString.charAt(scaleValue.length());
                if (nextChar == '0') {
                    return new BigDecimal(scaleValue);
                } else {
                    String[] amountPart2 = scaleValue.split("\\.");
                    boolean negative = amountPart2[0].charAt(0) == '-';
                    if (amountPart2.length == 2) {
                        int denominator = pow(10, amountPart2[1].length());
                        BigDecimal minFactor = BigDecimal.ONE.divide(new BigDecimal(denominator), 8, 4);
                        BigDecimal newValue = new BigDecimal(scaleValue);
                        newValue = newValue.add(negative ? minFactor.negate() : minFactor);
                        return newValue;
                    } else {
                        BigDecimal newValue = new BigDecimal(scaleValue);
                        newValue = newValue.add(negative ? BigDecimal.ONE.negate() : BigDecimal.ONE);
                        return newValue;
                    }
                }
            }
        }
    }

    public static List<String> getMacStringList() throws SocketException {
        List<String> macList = new LinkedList();
        Enumeration<NetworkInterface> allNetInterfaces = NetworkInterface.getNetworkInterfaces();

        while (allNetInterfaces.hasMoreElements()) {
            NetworkInterface netInterface = (NetworkInterface) allNetInterfaces.nextElement();
            if (!netInterface.isLoopback() && !netInterface.isVirtual() && !netInterface.isPointToPoint() && netInterface.isUp()) {
                byte[] mac = netInterface.getHardwareAddress();
                if (mac != null) {
                    String macStr = String.format("%02X-%02X-%02X-%02X-%02X-%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
                    macList.add(macStr);
                }
            }
        }

        return macList;
    }

    public static List<Long> getMacList() throws SocketException {
        byte[] macBuf = new byte[8];
        macBuf[6] = 1;
        macBuf[7] = 2;
        List<Long> macList = new LinkedList();
        Enumeration<NetworkInterface> allNetInterfaces = NetworkInterface.getNetworkInterfaces();

        while (allNetInterfaces.hasMoreElements()) {
            NetworkInterface netInterface = (NetworkInterface) allNetInterfaces.nextElement();
            if (!netInterface.isLoopback() && !netInterface.isVirtual() && !netInterface.isPointToPoint() && netInterface.isUp()) {
                byte[] mac = netInterface.getHardwareAddress();
                if (mac != null) {
                    System.arraycopy(mac, 0, macBuf, 0, 6);
                    Long macLong = decodeBigEndian(macBuf, 0, 8);
                    macList.add(macLong);
                }
            }
        }

        return macList;
    }

    public static Set<Long> getMacSet() throws SocketException {
        byte[] macBuf = new byte[8];
        macBuf[6] = 1;
        macBuf[7] = 2;
        Set<Long> macSet = new HashSet();
        Enumeration<NetworkInterface> allNetInterfaces = NetworkInterface.getNetworkInterfaces();

        while (allNetInterfaces.hasMoreElements()) {
            NetworkInterface netInterface = (NetworkInterface) allNetInterfaces.nextElement();
            if (!netInterface.isLoopback() && !netInterface.isVirtual() && !netInterface.isPointToPoint() && netInterface.isUp()) {
                byte[] mac = netInterface.getHardwareAddress();
                if (mac != null) {
                    System.arraycopy(mac, 0, macBuf, 0, 6);
                    Long macLong = decodeBigEndian(macBuf, 0, 8);
                    macSet.add(macLong);
                }
            }
        }

        return macSet;
    }

    public static List<Long> getMacListFromMacStringList(String[] macArray) throws SocketException {
        byte[] macBuf = new byte[8];
        macBuf[6] = 1;
        macBuf[7] = 2;
        List<Long> macList = new LinkedList();
        String[] var3 = macArray;
        int var4 = macArray.length;

        for (int var5 = 0; var5 < var4; ++var5) {
            String mac = var3[var5];
            String a = mac.substring(0, 2);
            String b = mac.substring(3, 5);
            String c = mac.substring(6, 8);
            String d = mac.substring(9, 11);
            String e = mac.substring(12, 14);
            String f = mac.substring(15);
            macBuf[0] = (byte) Integer.parseInt(a, 16);
            macBuf[1] = (byte) Integer.parseInt(b, 16);
            macBuf[2] = (byte) Integer.parseInt(c, 16);
            macBuf[3] = (byte) Integer.parseInt(d, 16);
            macBuf[4] = (byte) Integer.parseInt(e, 16);
            macBuf[5] = (byte) Integer.parseInt(f, 16);
            Long macLong = decodeBigEndian(macBuf, 0, 8);
            macList.add(macLong);
        }

        return macList;
    }


}
